﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using CxExtension;
using UnityExtensions;

namespace Config.CLV
{
	public partial class Clv
	{
		private static string mSpC = "\t";                      //
		private static readonly string[] mSp1 = { mSpC};                      //
		private static string[] mSp = { "\n"};                      //
		private static ObjectPool<StringBuilder>sPool = new ObjectPool<StringBuilder>() ;                      //

	

		
		public static void SaveTableList<T>(List<T> list,string path) where T : new()
		{
			var contents = ToClvString(list);
			File.WriteAllText(path,contents,Encoding.UTF8);
		}
		public static C ParseToListWithField<C,T>(StreamReader stream,C list, Action<C, T> addListAction) where T : new()
		{
			//ProfilerF.BeginSample("Clv.ParseToListWithField");
			var type = typeof(T);
			var fInfoMap = type.GetFieldInfoMapCache();
			ParseToList(stream,list,
				(T t, string key, string value) =>
			{
				var finfo = type.GetFieldInfoCache(fInfoMap,key);
				if (finfo == null) return;
				var v = finfo.FieldType.ParseValueByString(value);
				if (v == null) return;
				finfo.SetValue(t,v);
			},addListAction);
			//ProfilerF.EndSample();
			return list;
		}

		public static string ToClvString<T>(IList<T> self)
		{
			var type = typeof(T);
			var infos = type.GetSerializeFields(true);
			//var infoMap = infos.ToDictionary(it=>it.Name);
			var bld = sPool.Get();
			bld.Clear();

			var headLine = infos.Combine(it=>it.Name,mSpC);
			bld.AppendLine(headLine);

			foreach (var it in self)
			{
				var str = ToClvString(it, infos);
				bld.AppendLine(str);
			}

			return bld.ToString();
		}

		public static string ToClvString<T>(T self,IList<FieldInfo> infos)
		{
			var cont = infos.Combine(it => it.FieldType.SerializedToString(it.GetValue(self))/*(string)it.GetValue(self)*/,mSpC);
			//cont.SetValue();
			return cont;
		}

		public static C ParseToList<T,C>(StreamReader stream,C list, Action<T, string, string> setAction,Action<C,T> addListAction) where T : new()
		{
			var propStr = stream.ReadLine();
			Debug.Assert(propStr != null, "propStr != null");

			var propStrList = propStr.Split(mSp1, StringSplitOptions.None);
			do
			{
				var str = stream.ReadLine();
				if (str.IsNullOrEmpty())
				{
					break;
				}

				var t = new T();
				Parse(t,str, propStrList, setAction);
				addListAction(list, t);

			} while (true);

			return list;
		}

		public static T Parse<T>(T target,string text,IList<string> properList,Action<T,string,string> setAction) where T:new()
		{
			var sts = text.Split(mSp1,StringSplitOptions.None);
			var t = target;
			for (var i = 0; i < sts.Length; i++)
			{
				var key = properList[i];
				var value = sts[i];
				setAction(t, key, value);
			}

			return t;
		}
	}
}
